package me.aartikov.alligator.destinations;

import me.aartikov.alligator.converters.FragmentConverter;
import me.aartikov.alligator.helpers.FractionCache;
import me.aartikov.alligator.helpers.RunInfoStackHelp;
import me.aartikov.alligator.Screen;
import me.aartikov.alligator.ScreenResult;
import me.aartikov.alligator.helpers.MiFraction;
import me.aartikov.alligator.helpers.ScreenClassHelper;


public class FragmentDestination implements Destination {
    private Class<? extends Screen> mScreenClass;
    private FragmentConverter<? extends Screen> mFragmentConverter;

    private Class<? extends ScreenResult> mScreenResultClass;
    private ScreenClassHelper mScreenClassHelper;

    public FragmentDestination(Class<? extends Screen> screenClass,
                               FragmentConverter<? extends Screen> fragmentConverter,
                               Class<? extends ScreenResult> screenResultClass,
                               ScreenClassHelper screenClassHelper) {
        mScreenClass = screenClass;
        mFragmentConverter = fragmentConverter;
        mScreenResultClass = screenResultClass;
        mScreenClassHelper = screenClassHelper;
    }

    @SuppressWarnings("unchecked")
    public MiFraction createFragment(Screen screen) {
        MiFraction fragment = FractionCache.getInstance().get(screen);
        if (fragment == null) {
            fragment = ((FragmentConverter<Screen>) mFragmentConverter).createFragment(screen);
            FractionCache.getInstance().put(screen, fragment);
        }
        checkScreenClass(screen.getClass());
        fragment.setGouptag(RunInfoStackHelp.getInstance().getDate(screen.getGroup()));
        fragment.setParentId(screen.getmContainerId());
        mScreenClassHelper.putScreenClass(fragment, screen.getClass());
        return fragment;
    }


    public Screen getScreen(MiFraction fragment) {
        return mFragmentConverter.getScreen(fragment);
    }


    public Class<? extends ScreenResult> getScreenResultClass() {
        return mScreenResultClass;
    }

    private void checkScreenClass(Class<? extends Screen> screenClass) {
        if (!mScreenClass.isAssignableFrom(screenClass)) {
            throw new IllegalArgumentException("Invalid screen class " + screenClass.getSimpleName() + ". Expected " + mScreenClass.getSimpleName());
        }
    }
}